﻿// -------------------------------------------------------------------------
//    @FileName         :    NFWorldPlayer.h
//    @Author           :    gaoyi
//    @Date             :   2023-07-10
//    @Email			:    445267987@qq.com
//    @Module           :    NFWorldPlayer.h
//
// -------------------------------------------------------------------------

#pragma once

#include "NFComm/NFObjCommon/NFObjPtr.h"
#include "NFComm/NFShmStl/NFShmVector.h"
#include "NFComm/NFPluginModule/NFIMessageModule.h"
#include "NFComm/NFPluginModule/NFCircularBuffer.h"
#include "NFLogicCommon/NFLogicShmTypeDefines.h"
#include "NFPlayerBase.h"
#include "NFServerComm/NFServerCommon/NFCacheDataWithSaveDb.h"

class NFPart;
class NFSession;

class NFPlayer : public NF_OBJECT_TEMPLATE_MACRO(NFPlayer, EOT_LOGIC_PLAYER_ID, NFCacheData, public NFPlayerBase)
public:
    NFPlayer();

    ~NFPlayer() override;

    int CreateInit();

    int ResumeInit();

    int OnTimer(int timeId, int callCount) override;

    int OnExecute(uint32_t serverType, uint32_t nEventID, uint32_t bySrcType, uint64_t nSrcID, const google::protobuf::Message* pMessage) override;

public:
    bool IsCanLogout() override;

    int DoOnline() override;

    bool IsCanDelete() override;

    int DoLogout() override;

public:
    int Init() override;

    int UnInit() override;

    /**
     * @brief
     * @param data
     * @return
     */
    int LoadFromDB(const proto_ff::tbRoleDetail* pDbData, const RoleOne& stRoleOne) override;

    /**
     * @brief
     * @param data
     * @return
     */
    int InitConfig(proto_ff::tbRoleDetail* pDbData, const RoleOne& stRoleOne) override;

    /**
     * @brief
     * @param data
     * @return
     */
    int SaveDB(proto_ff::tbRoleDetail* pDbData) override;

    int SaveRoleSimpleInfo(proto_ff::Proto_RoleSimpleInfo* pDbData) override;

    /**
     * @brief
     * @return
     */
    int LogicTick() override;

    /**
     * @brief 注册后的初始化
     * @return
     */
    int OnRegister() override;

    /**
     * @brief 登陆入口
     * @return
     */
    int OnLogin() override;

    /**
     * @brief 登出入口
     * @return
     */
    int OnLogout() override;

    /**
     * @brief 掉线入口
     * @return
     */
    int OnDisconnect() override;

    /**
     * @brief 重连入口
     * @return
     */
    int OnReconnect() override;

    ////////////////////////////////// 每日每周刷新接口 ///////////////////////////////////
    /**
     * @brief 每日刷新接口
     * @return
     */
    int DayTick() override;

    /**
     * @brief 每日4点/6点刷新接口
     * @return
     */
    int DayOtherTick() override;

    /**
     * @brief 每周刷新接口
     * @return
     */
    int WeekTick() override;

    /**
     * @brief 每月刷新接口
     * @return
     */
    int MonthTick() override;

    /**
     * @brief 每秒刷新接口
     * @return 0 表示成功，其他为错误码
     */
    int SecTick() override;

    /**
     * @brief 每5秒刷新接口
     * @return 0 表示成功，其他为错误码
     */
    int FiveSecTick() override;

    /**
     * @brief 每分钟刷新接口
     * @return 0 表示成功，其他为错误码
     */
    int MinuteTick() override;

    /**
     * @brief 每5分钟刷新接口
     * @return 0 表示成功，其他为错误码
     */
    int FiveMinuteTick() override;

    /**
     * @brief 每小时刷新接口
     * @return 0 表示成功，其他为错误码
     */
    int HourTick() override;

public:
    int MakePlayerDataCS(proto_ff::Proto_CSGetRoleRsp* pCSGetRoleRsp) override;
    int MakeCityPlayerData(proto_ff::CityRoleInfo* pGCCityRoleInfo) override;

public:
    void SetRoleID(uint64_t ullRoleID)
    {
        m_ullRoleId = ullRoleID;
    }

    uint64_t GetRoleID() const
    {
        return m_ullRoleId;
    }

public:
    /**
     * @brief
     * @return
     */
    virtual bool IsInBattle();

    /**
     *
     * @return
     */
    virtual bool IsInTransSceneing();

public:
    /**
     * \brief 处理继承NFISaveDB
     */
    bool IsNeedSave() const override;

    /**
     * @brief
     * @param iReason
     * @return
     */
    int SendTransToDb(int iReason = TRANS_SAVEROLEDETAIL_NORMAL) override;

    /**
     * @brief
     * @return
     */
    uint32_t GetAllSeq() const override;

    /**
     * @brief
     */
    void ClearAllSeq() override;

    int GetCacheCreateTimeoutSec() const override
    {
        return std::numeric_limits<int>::max();
    }

    int GetCacheExpireTimeSec() const override
    {
        return std::numeric_limits<int>::max();
    }

public:
    template <typename PART>
    PART* GetPart()
    {
        return dynamic_cast<PART*>(GetPart(PART::GetStaticClassType() - EOT_LOGIC_PART_MIN_ID));
    }

    template <typename PART>
    const PART* GetPart() const
    {
        return dynamic_cast<const PART*>(GetPart(PART::GetStaticClassType() - EOT_LOGIC_PART_MIN_ID));
    }

    template <typename PART>
    PART* GetPart(uint32_t partType)
    {
        return dynamic_cast<PART*>(GetPart(partType));
    }

    template <typename PART>
    const PART* GetPart(uint32_t partType) const
    {
        return dynamic_cast<const PART*>(GetPart(partType));
    }

    NFPart* GetPart(uint32_t partType);

    const NFPart* GetPart(uint32_t partType) const;

    /**
     * @brief 创建Part
     * @param partType
     * @param dbData
     * @return
     */
    NFPart* CreatePart(uint32_t partType);

    /**
     * @brief 释放Part
     * @param pPart
     * @return
     */
    int RecylePart(NFPart* pPart);

public:
    uint64_t StatusId() const override
    {
        return m_ullRoleId;
    }

    uint64_t GetCacheId() const override
    {
        return m_ullRoleId;
    }

private:
    uint64_t m_ullRoleId;
    NFShmVector<NFObjPtr<NFPart>, PART_MAX> m_pPart;

public:
    NFSession* GetClientSession();

    NFSession* GetClientSessionFast();

    int BindClientSession(NFSession* pSession);
    int UnBindClientSession();

    int GetClientSessionID() const
    {
        return m_iClientSessionID;
    }

private:
    int m_iClientSessionID;
    NFObjPtr<NFSession> m_pClientSession;

public:
    void SetRoleDetailSyned()
    {
        m_bIsSyncedRoleDetail = true;
    }

    bool GetRoleDetailSyned() const
    {
        return m_bIsSyncedRoleDetail;
    }

private:
    bool m_bIsSyncedRoleDetail;

public:
    int CleanupCache();

    int CacheMsgRes(uint16_t wCmd, uint16_t wSeq, const char* pBin, size_t iSize);

    int SendCachedMsgRes(uint16_t wSeq);

public:
    virtual int SendMsgToClient(uint32_t nMsgId, const google::protobuf::Message& xData);

    virtual int SendMsgToSnsServer(uint32_t nMsgId, const google::protobuf::Message& xData);

    virtual int SendMsgToWorldServer(uint32_t nMsgId, const google::protobuf::Message& xData);

    virtual int SendMsgToGameServer(uint32_t nMsgId, const google::protobuf::Message& xData);

    virtual int SendMsgToCityServer(uint32_t nMsgId, const google::protobuf::Message& xData);
    virtual int SendTransToCityServer(uint32_t nMsgId, const google::protobuf::Message& xData, int transReq, int transRsp);

    virtual int SendMsgToOnlineServer(uint32_t nMsgId, const google::protobuf::Message& xData);
    virtual int SendTransToOnlineServer(uint32_t nMsgId, const google::protobuf::Message& xData, int transReq, int transRsp);

private:
    uint16_t m_wLastPopedServerSeq; //last poped server seq
    enum { MAX_CACHED_MSG_SIZE = 64 * 1024 }; //cache size
    CircularBuffer<uint16_t, MAX_CACHED_MSG_SIZE> m_CSMsgBinCache;

public:
    void SetEventLogFlag(bool flag)
    {
        m_bEventLogFlag = flag;
    }

    bool GetEventLogFlag() const
    {
        return m_bEventLogFlag;
    }

private:
    bool m_bEventLogFlag;

public:
    void SetIsCreateLogin(const bool flag)
    {
        m_bIsCreateLogin = flag;
    }

    bool GetIsCreateLogin()
    {
        return m_bIsCreateLogin;
    }

private:
    bool m_bIsCreateLogin; //首次创建账号登陆
public:
    void BindAccount(int iPlayerAccountId)
    {
        m_iPlayerAccountId = iPlayerAccountId;
    }

    int GetAccountId() const
    {
        return m_iPlayerAccountId;
    }

private:
    int32_t m_iPlayerAccountId;

public:
    int SendSyncData();

private:
    int32_t m_lastOnlineSyncTime;

public:
    int GetLoginZoneId() const
    {
        return m_loginZoneId;
    };
    int32_t m_loginZoneId;

public:
    int GetDungeonID()
    {
        return m_iDungeonID;
    }

    int SetDungeonID(int iID)
    {
        m_iDungeonID = iID;

        return 0;
    }

    uint64_t GetDungeonUID()
    {
        return m_ullDungeonUID;
    }

    int SetDungeonUID(uint64_t ullID)
    {
        m_ullDungeonUID = ullID;

        return 0;
    }

    int GetDungeonAwardID()
    {
        return m_iDungeonAwardID;
    }

    int SetDungeonAwardID(int iDungeonAwardID)
    {
        m_iDungeonAwardID = iDungeonAwardID;

        return 0;
    }

public:
    //dungeon
    int m_iDungeonID;
    uint64_t m_ullDungeonUID;
    int m_iDungeonAwardID;
    uint64_t m_ullLastFinishBattleCostTime;
};
